﻿using NetDh.Lib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace NetDh.Presentation.Common
{
    public class MvcActionFilterAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 是否可匿名访问(不做身份验证)
        /// </summary>
        public bool AllowAnonymous { get; set; }

        //可以灵活定义属性判断
        /// <summary>
        /// 增加用户类型（角色）权限判断。
        /// </summary>
        public string[] UserTypes { get; set; }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //base.OnActionExecuting(filterContext);//基类为空函数。
            //if (HttpContext.Current.Request.HttpMethod.ToUpper() != "HEAD")
            //filterContext.HttpContext.Items[SlowHttpTracer.TRACERT_KEY] = DateTime.Now;//->和UserToken合并为一个对象。
            UserToken curToken = null;
            void funcNoAuthenticatedResult(bool needSignOut = false)
            {
                curToken = UserToken.CreateEmptyInstance();
                if (AllowAnonymous) return;
                //IsAjaxRequest源码:request["X-Requested-With"] == "XMLHttpRequest" || (request.Headers != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    //mvc 需要区分是ajax请求还是页面请求，否则可能报错“服务器无法在发送 HTTP 标头之后设置内容类型”，“服务器无法在已发送 HTTP 标头之后设置状态”
                    //而api没有页面请求，不需要区分。
                    //前端js需要配合跳到登录页。
                    filterContext.Result = new ContentResult() { Content = "need login!" };//简单字符串返回就好。也可用JsonResult。
                    //filterContext.Result = new HttpUnauthorizedResult("need login");//跳转到默认的登录页面，根据config中设置的loginUrl，产生默认页面类似: <a href="/login.aspx?ReturnUrl=%2fhome%2fTestNewJson">here</a>
                }
                else
                {
                    //跳转到指定的登录页面
                    filterContext.Result = needSignOut ? new RedirectResult("/login/signOut") : new RedirectResult("/login");
                }
            }

            //mvc的身份验证是根据web.config中设置的<authentication mode="Forms">，即cookie验证。
            if (!HttpContext.Current.User.Identity.IsAuthenticated) //cookie 过期 跳转到登陆页面
            {
                funcNoAuthenticatedResult();
            }
            else
            {
                string ticket = ((FormsIdentity)HttpContext.Current.User.Identity).Ticket.UserData;
                curToken = TokenHelper.GetToken(ticket);
                if (curToken == null)
                {
                    funcNoAuthenticatedResult(true);
                }
                else
                {
                    if (UserTypes != null && !UserTypes.Contains(curToken.UserType))
                    {
                        if (filterContext.HttpContext.Request.IsAjaxRequest())
                        {
                            filterContext.Result = new ContentResult() { Content = "need authorized!" };
                        }
                        else
                        {
                            //filterContext.Result = new RedirectResult("/bad/http401");
                            //filterContext.HttpContext.Response.Clear();
                            //filterContext.HttpContext.Response.ContentType = "text/html; charset=utf-8";
                            //filterContext.HttpContext.Response.WriteFile("~/badhttp/http401.html");//这种写法只是添加Response内容，仍然会往下执行到Action，返回Action。
                            //filterContext.Result = new RedirectResult("~/badhttp/http401.html");//这种写法url变掉。
                            filterContext.Result = new FilePathResult("~/badhttp/http401.html", "text/html; charset=utf-8");
                        }
                    }
                }
            }
            curToken._HttpTime = DateTime.Now;
            filterContext.HttpContext.Items[TokenHelper.TOKEN_NAME] = curToken;
        }
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            //if (HttpContext.Current.Request.HttpMethod.ToUpper() != "HEAD")
            var curToken = filterContext.HttpContext.Items[TokenHelper.TOKEN_NAME] as UserToken;
            if (curToken != null)
            {
                SlowHttpTracer.CheckLog(curToken, WebPlatform.mvc);
            }
            base.OnActionExecuted(filterContext);
        }
        //public override void OnResultExecuting(ResultExecutingContext filterContext);//加载视图前 filterContext.HttpContext.Response.Write("OnResultExecuting")
        //public override void OnResultExecuted(ResultExecutedContext filterContext);//加载视图后

    }
}
